<template>
  <div>
    <div id="body-test" style="width: 100%; height: 100%">
      <div
        id="container"
        class="item"
        :style="{
          width: containerWidth,
          height: containerHeight,
          cursor: cursorValue,
        }"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      containerWidth: 200,
      containerHeight: 200,
      resizeable: false,
      clientX: 0,
      clientY: 0,
      minW: 8,
      minH: 8,
      direc: "",
      boxItem: null,
      cursorValue: "",
      isDown: false,
      moveX: 0,
      moveY: 0,
      offsetX: 0,
      offsetY: 0,
      curX: 0,
      curY: 0,
    };
  },
  mounted() {
    this.boxItem = document.getElementById("container");
    // body监听移动事件
    document.getElementById("body-test").addEventListener("mousemove", (e) => {
      e.stopPropagation();
      this.move(e);
    });
    // 鼠标按下事件
    document.getElementById("container").addEventListener("mousedown", (e) => {
      let d = this.getDirection(e);

      // 当位置为四个边和四个角时才开启尺寸修改
      if (d !== "") {
        this.resizeable = true;
        this.direc = d;
        this.clientX = e.clientX;
        this.clientY = e.clientY;
      } else {
        this.moveX = e.clientX;
        this.moveY = e.clientY;
        this.isDown = true;
      }
    });
    document.getElementById("container").addEventListener("mousemove", (e) => {
      if (this.isDown) {
        e.stopPropagation();
        this.cursorValue = "move";
        this.curX = this.offsetX + e.clientX - this.moveX;
        this.curY = this.offsetY + e.clientY - this.moveY;
        this.boxItem.style.transform = `translate(${this.curX + "px"},${
          this.curY + "px"
        })`;
      }
    });
    document.getElementById("container").addEventListener("mouseup", (e) => {
      e.stopPropagation();
      this.offsetX = this.curX;
      this.offsetY = this.curY;
      this.resizeable = false;
      this.isDown = false;
    });
    // 鼠标松开事件
    document.getElementById("body-test").addEventListener("mouseup", () => {
      e.stopPropagation();
      this.resizeable = false;
    });
  },
  methods: {
    // 鼠标移动事件
    move(e) {
      let d = this.getDirection(e);
      let cursor;
      if (d === "") cursor = "default";
      else cursor = d + "-resize";
      // 修改鼠标显示效果
      this.cursorValue = cursor;
      // 当开启尺寸修改时，鼠标移动会修改div尺寸
      if (this.resizeable) {
        // 鼠标按下的位置在右边，修改宽度
        if (this.direc.indexOf("e") !== -1) {
          this.containerWidth =
            Math.max(
              this.minW,
              this.boxItem.offsetWidth + (e.clientX - this.clientX)
            ) + "px";
          this.clientX = e.clientX;
        }

        // 鼠标按下的位置在上部，修改高度
        if (this.direc.indexOf("n") !== -1) {
          this.containerHeight =
            Math.max(
              this.minH,
              this.boxItem.offsetHeight + (this.clientY - e.clientY)
            ) + "px";
          this.clientY = e.clientY;
        }
        // 鼠标按下的位置在底部，修改高度
        if (this.direc.indexOf("s") !== -1) {
          this.containerHeight =
            Math.max(
              this.minH,
              this.boxItem.offsetHeight + (e.clientY - this.clientY)
            ) + "px";
          this.clientY = e.clientY;
        }

        // 鼠标按下的位置在左边，修改宽度
        if (this.direc.indexOf("w") !== -1) {
          this.containerWidth =
            Math.max(
              this.minW,
              this.boxItem.offsetWidth + (this.clientX - e.clientX)
            ) + "px";
          this.clientX = e.clientX;
        }
      }
    },
    // 获取鼠标所在div的位置
    getDirection(ev) {
      let xP, yP, offset, dir;
      dir = "";
      xP = ev.offsetX;
      yP = ev.offsetY;
      offset = 10;

      if (yP < offset) dir += "n";
      else if (yP > this.boxItem.offsetHeight - offset) dir += "s";
      if (xP < offset) dir += "w";
      else if (xP > this.boxItem.offsetWidth - offset) dir += "e";

      return dir;
    },
  },
};
</script>

<style>
#container {
  width: 200px;
  height: 200px;
  padding: 15px;
  border: #00cdcd 2px solid;
  box-sizing: border-box;
}

.item {
  cursor: default;
  width: 100%;
  height: 100%;
}
</style>
